<?php
namespace app\task\controller;
use app\common\library\wechat\WxBizMsgCrypt;
use app\task\model\Config as ConfigModel;
use app\task\model\Wxapp as WxappModel;
use app\task\model\WxappName as WxappNameModel;
use app\task\model\WxappReg as WxappRegModel;
use think\Cache;
/**
 * 第三方平台与微信通讯接口
 */

class Callback
{
    /**
     * 异步通知处理
     */
    public function ticket()
    {
		//获取第三方配置信息
		$config = ConfigModel::detail();
		// 接收公众号平台发送的消息
		$timeStamp = empty ( $_GET ['timestamp']) ? "" : trim ( $_GET ['timestamp'] );
        $nonce = empty ( $_GET ['nonce'] ) ?"" : trim ( $_GET ['nonce'] );
        $msg_signature = empty ( $_GET['msg_signature'] ) ? "" : trim ( $_GET ['msg_signature'] );
        $encryptMsg = file_get_contents ('php://input' );
        //创建解密类
		$pc = new WxBizMsgCrypt($config['token'], $config['encoding_aes_key'], $config['app_id']);
		$msg = '';
		$errCode = $pc->decryptMsg($msg_signature, $timeStamp, $nonce, $encryptMsg, $msg);
		if($errCode == 0){
			$data = _xmlToArr($msg);	//XML转换为数组
			//write_log($data, __DIR__);//用于测试callback.php接口
			//推送的ticket
			if($data['InfoType'] == 'component_verify_ticket'){
				$config->component_verify_ticket = $data['ComponentVerifyTicket']; 
				//更新过期的令牌component_access_token
				if($config['expires_in'] < time()){
					//过期更新access_token
					$token = $this->getToken($config['app_id'], $config['app_secret'], $config->component_verify_ticket);
					$config->component_access_token = $token['component_access_token'];
					$config->expires_in = time()+7000;
				}
				$config->save();	//保存ticket
			}
			//取消授权
			if($data['InfoType'] == 'unauthorized'){
				if($config['wechat_appid'] == $data['AuthorizerAppid']){
					$config->wechat_appid = '';//官方公众号取消授权
					$config->save();
				}else{
					if($wxapp = WxappModel::getWxapp(['app_id' => $data['AuthorizerAppid']])){
						$wxapp->edit([
							'is_empower' => 0,	//0=取消授权
							'app_id' => '',	//app_id值空，否则影响下次授权
						]);
					}
				}
			}
			//更新授权
			if($data['InfoType'] == 'updateauthorized'){
				/*
				Array
				(
					[AppId] => wxd081a139beb02c77
					[CreateTime] => 1572001402
					[InfoType] => updateauthorized
					[AuthorizerAppid] => wxfd9875920f95854c
					[AuthorizationCode] => queryauthcode@@@x51tQWCqAh2vrSm6LOkLUDEvazWHdq8bZ05mwEwMDVGCBVZiydGjEMhbO0qDTriq-7F1sFNuicI_lqSp4SWUqg
					[AuthorizationCodeExpiredTime] => 1572005002
					[PreAuthCode] => preauthcode@@@eJqcbkFUN6N1hrO1S4H_zymHzftXj902fhTR5EM1zUCFHCUmSYISd-dYq_Gt_x0w
				)
				*/
			}
			
			/*
			//成功授权
			if($data['InfoType'] == 'authorized'){
				//转移到 store/wxapp/authorize
			}
			*/
			//小程序注册成功
			if($data['InfoType'] == 'notify_third_fasteregister'){
				//验证状态
				$this->fasteregister($data,$config);				
			}
			//名称审核结果事件推送
			if($data['MsgType'] == 'event'){
				$wxapp = WxappModel::getWxapp(['user_name' => $data['ToUserName']]); //获取商户数据
				$setName = WxappNameModel::detail($wxapp['wxapp_id']);
				if($data['ret']==2){
					$setName['status'] = 2;
					$setName['reason'] = $data['reason'];
					$setName->save();
				}
				if($data['ret']==3){
					$setName['status'] = 1;
					$setName->save();
					$wxapp['app_name'] = $data['nickname'];
					$wxapp->save();
					Cache::rm('wxapp_' . $wxapp['wxapp_id']);
				}
				if($data['Event'] == 'wxa_nickname_audit'){
					write_log('审核通知', __DIR__);
				}
				if($data['Event'] == 'weapp_audit_success'){
					write_log('审核通过', __DIR__);
				}
				if($data['Event'] == 'weapp_audit_fail'){
					write_log('审核不通过', __DIR__);
				}
				if($data['Event'] == 'weapp_audit_delay'){
					write_log('审核延后', __DIR__);
				}
				write_log($data, __DIR__);				
			}
			return 'success';
		}else{
			write_log('Callback 解密失败 - 错误代码：'.$errCode, __DIR__);
		}
    }
	
	/**
     * 获取 component_access_token
    */
	private function getToken($appid, $appsecret, $ticket)
	{
		$url = 'https://api.weixin.qq.com/cgi-bin/component/api_component_token';
		$data = '{"component_appid":"'.$appid.'","component_appsecret":"'.$appsecret.'","component_verify_ticket":"'.$ticket.'"}';
		return json_decode(http_request($url,$data),true);
	}
	
	/**
     * 快速注册小程序状态验证
    */
	private function fasteregister($data,$config)
	{
		//获取申请小程序记录详情
		$detail = WxappRegModel::detail([
			'legal_name' => $data['info']['name'],
			'legal_persona_wechat' => $data['info']['legal_persona_wechat'],
			'legal_persona_name' => $data['info']['legal_persona_name'],
			'status' => 20
		]);
		write_log('输出小程序申请表',__DIR__);
		write_log($detail,__DIR__);
		//判断微信端审核状态
		if($data['status']==0){
			sand_examine_msg($detail['wxapp_reg_id'],'微信小程序注册成功','注册成功',$detail['wxapp_id']);
			//审核成功 - 获取授权信息
			$result = getAuth($config['app_id'], $config['component_access_token'], $data['auth_code']);
			$auth = $result['authorization_info'];//得到授权信息
			write_log($auth,__DIR__);
			//获取授权应用的帐号基本信息
			$result = getAppInfo($config['app_id'], $config['component_access_token'], $auth['authorizer_appid']);
			$app = $result['authorizer_info'];//得到授权应用的帐号基本信息
			write_log($app,__DIR__);	
			$wxapp = WxappModel::getWxapp(['wxapp_id' => $detail['wxapp_id']]); //获取商户数据
			write_log($wxapp,__DIR__);
			$wxapp->edit([
				'user_name' => $app['user_name'],					//原始ID
				'principal_name' => $app['principal_name'],			//主体名称
				'app_id' => $auth['authorizer_appid'],				//授权方APPid
				'access_token' => $auth['authorizer_access_token'],	//令牌
				'expires_in' => time()+7000,						//令牌过期时间
				'authorizer_refresh_token' => $auth['authorizer_refresh_token'],	//刷新令牌
				'is_empower' => 1,	//是否授权
				'source' => 20 //注册来源
			]);
			$detail->status = 30;
		}else{
			//审核失败
			$status = [
				100001 => '已下发的模板消息法人并未确认且已超时（24h），未进行身份证校验',
				100002 => '已下发的模板消息法人并未确认且已超时（24h），未进行人脸识别校验',
				100003 => '已下发的模板消息法人并未确认且已超时（24h）',
				101 => '工商数据返回：“企业已注销”',
				102 => '工商数据返回：“企业不存在或企业信息未更新”',
				103 => '工商数据返回：“企业法定代表人姓名不一致”',
				104 => '工商数据返回：“企业法定代表人身份证号码不一致”',
				105 => '法定代表人身份证号码，工商数据未更新，请 5-15 个工作日之后尝试',
				1000 => '工商数据返回：“企业信息或法定代表人信息不一致”',
				1001 => '主体创建小程序数量达到上限',
				1002 => '主体违规命中黑名单',
				1003 => '管理员绑定账号数量达到上限',
				1004 => '管理员违规命中黑名单',
				1005 => '管理员手机绑定账号数量达到上限',
				1006 => '管理员手机号违规命中黑名单',
				1007 => '管理员身份证创建账号数量达到上限',
				1008 => '管理员身份证违规命中黑名单'
			];
			if($data['status'] == -1){
				$detail->reject = '企业与法人姓名不一致';
			}else{
				if(isset($status[$data['status']])){
					$detail->reject = $status[$data['status']];
				}else{
					$detail->reject = '未知原因';
				}
			}	
			$detail->status = 40;
			sand_examine_msg($detail['wxapp_reg_id'],'注册信息被驳回','注册失败',$detail['wxapp_id']);
		}
		$detail->save();
		return true;
	}
}
